const { calcAccuracySummary } = require("./calcAccuracySummary");
const _ = require("lodash");

/**
 * 高级选号策略引擎（流式输出）
 * @param {Object} config - 配置对象
 * @param {Function} config.onEachPeriod - 每期处理完后的回调 (写入/上传等)
 */
function enhancedSelectGroups({
  groupAccuracyMap,
  flatGroupMap,
  numberGroupMap,
  historyData,
  windowSize = 200,
  cooldownThreshold = 3,
  cooldownPeriod = 10,
  diversityLimit = 4,
  recentHotWindow = 3,
  maxRecentRepeat = 2,
  onEachPeriod,
}) {
  const groupCooldownMap = {}; // groupName => index
  const allNumbers = Array.from({ length: 49 }, (_, i) =>
    i + 1 < 10 ? `0${i + 1}` : `${i + 1}`
  );

  for (let i = windowSize; i < historyData.length; i++) {
    const currentData = historyData[i];
    const lastNumber = historyData[i - 1].number;

    const killNextAccuracyMap = _.mapValues(groupAccuracyMap, (arr) =>
      arr.slice(i - windowSize - 1, i - 1)
    );

    const stats = Object.entries(killNextAccuracyMap).map(
      ([groupName, data]) => ({
        key: groupName,
        value: calcAccuracySummary(data),
      })
    );

    // 冷却机制
    stats.forEach(({ key, value }) => {
      if (value.currentConsecutiveIncorrect >= cooldownThreshold) {
        groupCooldownMap[key] = i + cooldownPeriod;
      }
    });
    const cooledGroups = Object.entries(groupCooldownMap)
      .filter(([_, until]) => until >= i)
      .map(([group]) => group);

    // 多策略评分
    const strategies = [
      (v) => v.score,
      (v) => v.accuracyRate,
      (v) => v.decayAccuracyScore,
    ];
    const voteCounter = {};

    strategies.forEach((scoreFn) => {
      stats
        .filter((s) => !cooledGroups.includes(s.key))
        .sort((a, b) => scoreFn(b.value) - scoreFn(a.value))
        .slice(0, 30)
        .forEach((s) => {
          voteCounter[s.key] = (voteCounter[s.key] || 0) + 1;
        });
    });

    const topVotedGroups = Object.entries(voteCounter)
      .sort((a, b) => b[1] - a[1])
      .slice(0, 40)
      .map(([group]) => group);

    // 热号识别
    const recentNumbers = historyData
      .slice(i - recentHotWindow, i)
      .map((d) => d.number);
    const hotNumbers = Object.entries(_.countBy(recentNumbers))
      .filter(([_, count]) => count >= maxRecentRepeat)
      .map(([n]) => n);

    // 多样性选号逻辑
    const selectedNumbers = new Set();
    const groupContributionCount = {};

    for (const groupName of topVotedGroups) {
      const group = flatGroupMap[groupName];
      const killIndex = numberGroupMap[lastNumber]?.[groupName];
      group.forEach((subgroup, idx) => {
        if (idx === killIndex) return;
        if (!groupContributionCount[groupName])
          groupContributionCount[groupName] = 0;

        subgroup.forEach((num) => {
          const padded = num.toString().padStart(2, "0");
          if (
            selectedNumbers.size < 32 &&
            !selectedNumbers.has(padded) &&
            !hotNumbers.includes(padded) &&
            groupContributionCount[groupName] < diversityLimit
          ) {
            selectedNumbers.add(padded);
            groupContributionCount[groupName]++;
          }
        });
      });
      if (selectedNumbers.size >= 32) break;
    }

    const result = {
      index: i,
      date: currentData.time,
      number: currentData.number,
      selectedNumbers: Array.from(selectedNumbers),
      isAccurate: selectedNumbers.has(currentData.number),
      usedGroups: topVotedGroups,
    };

    onEachPeriod?.(result); // ✅ 写入或回调处理
  }
}

module.exports = enhancedSelectGroups;
